import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:flutter_syt/application.dart';
import 'package:flutter_syt/generated/l10n.dart';
import 'package:flutter_syt/theme/theme_color.dart';
import 'package:flutter_syt/utils/click_utils.dart';
import 'package:flutter_syt/utils/utils_other.dart';
import 'package:table_calendar/table_calendar.dart';

class EventScheduleCalendar extends StatefulWidget {
  EventScheduleCalendar({Key? key, required this.action}) : super(key: key);

  final EventCalendarAction action;

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _EventScheduleCalendar();
  }
}

class _EventScheduleCalendar extends State<EventScheduleCalendar> {
  late DateTime date;
  List<CalendarItemData> monthDayList = [];
  ScrollController controller = ScrollController();

  var _preLoadSecond = 0;
  DateTime? _preTime;
  late DateTime _showTime;
  @override
  void initState() {
    super.initState();
    // _showTime
    // DateTime newDate = DateTime.now();
    // DateTime newDate = DateTime.utc(2023, 8, 8);

    // DateTime beginDate = _firstDayOfMonth();
    // DateTime endDate = _lastDayOfMonth();
    DateTime showDate = UtilsOther.getShowDate();

    // if (beginDate.difference(newDate).inDays > 0) {
    _showTime = showDate;
    // date = beginDate;
    // widget.action.selectDay = beginDate;
    // } else if (newDate.difference(endDate).inDays > 0) {
    //   _showTime = endDate;
    //   date = endDate;
    //   widget.action.selectDay = endDate;
    // } else {
    //   date = newDate;
    //   _showTime = newDate;
    //   widget.action.selectDay = newDate;
    // }
    // Future.delayed(Duration(milliseconds: 50), () {
    //   widget.action.back(date);
    // });
    // widget.action.back(date);
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      if (timeStamp.inSeconds == _preLoadSecond) {
        return;
      }
      if (isSameDay(date, _preTime)) {
        return;
      }
      _preLoadSecond = timeStamp.inSeconds;
      _preTime = date;
      var index = (date.month == 7 ? date.day - 27 : date.day).toDouble();
      // if (index - 3.5 > 0) {
      //   index = index - 3.5;
      // } else {
      //   index -= 1;
      // }
      controller.animateTo((index) * 64,
          duration: Duration(milliseconds: 250), curve: Curves.easeIn);
    });
  }

  @override
  Widget build(BuildContext context) {
    date = widget.action.selectDay;

    return Column(
      children: [
        header(),
        list(),
      ],
    );
  }

  Widget header() {
    var local =
        appContext.storage.getString("storyLocal") ?? Intl.getCurrentLocale();

    return Container(
        alignment: Alignment.centerLeft,
        padding: EdgeInsets.symmetric(horizontal: 15, vertical: 10),
        child: Text(
          local.contains('zh')
              ? '${_showTime.year} ${DateFormat('MMM', Intl.getCurrentLocale()).format(_showTime)}'
              : '${DateFormat('MMM', Intl.getCurrentLocale()).format(_showTime)} ${_showTime.year}',
          style: TextStyle(
              fontSize: 14,
              fontWeight: FontWeight.w500,
              color: ThemeColor.colorBlack100),
        )
        // child: Row(
        //   mainAxisSize: MainAxisSize.min,
        //   children: [
        // SizedBox(
        //   height: 20,
        //   width: 20,
        //   child: IconButton(
        //     onPressed: ClickUtils.debounce(() {
        //       setState(() {
        //         _showTime = _dayofMonth(_showTime, true);
        //       });
        //     }),
        //     icon: Image.asset("assets/icons/event_calendar_left_arrow.png",
        //         width: 14, height: 13),
        //     padding: EdgeInsets.all(0),
        //   ),
        // ),

        // TextButton(
        //     onPressed: ClickUtils.debounce(() {
        //       // showFilterDialog(
        //       //     context,
        //       //     EventCalendarAction((data) {
        //       //       if (data is DateTime) {
        //       //         _showTime = data;
        //       //       }
        //       //       widget.action.back(data);
        //       //     }, widget.action.selectDay, widget.action.matchList));
        //     }),
        //     child: Text(
        //       '${_showTime.year} ${DateFormat('MMM', Intl.getCurrentLocale()).format(_showTime)}',
        //       style: TextStyle(
        //           fontSize: 14,
        //           fontWeight: FontWeight.w500,
        //           color: ThemeColor.colorBlack100),
        //     )),
        // SizedBox(
        //   height: 20,
        //   width: 20,
        //   child: IconButton(
        //     onPressed: ClickUtils.debounce(() {
        //       _showTime = _dayofMonth(_showTime, false);
        //       setState(() {});
        //     }),
        //     icon: Image.asset("assets/icons/event_calendar_right_arrow.png",
        //         width: 14, height: 13),
        //     padding: EdgeInsets.all(0),
        //   ),
        // ),
        // Spacer(),
        // GestureDetector(
        //   child: Row(
        //     children: [
        //       Image.asset("assets/icons/schedule_location.png",
        //           width: 10, height: 11),
        //       SizedBox(
        //         width: 4,
        //       ),
        //       Text(
        //         S().Back_to_Today,
        //         style: TextStyle(
        //             fontWeight: FontWeight.w400,
        //             fontSize: 12,
        //             color: ThemeColor.colorBlack60),
        //       ),
        //     ],
        //   ),
        //   onTap: ClickUtils.debounce(() {
        //     _showTime = now;
        //     widget.action.back(now);
        //   }),
        // ),
        // ],
        // ),
        );
  }

// DateTime month
  DateTime _firstDayOfMonth() {
    return DateTime.utc(2023, 7, 27);
    // return DateTime.utc(month.year, month.month, 1);
  }

// DateTime month
  DateTime _lastDayOfMonth() {
    return DateTime.utc(2023, 8, 9);
    // final date = month.month < 12
    //     ? DateTime.utc(month.year, month.month + 1, 1)
    //     : DateTime.utc(month.year + 1, 1, 1);
    // return date.subtract(const Duration(days: 1));
  }

  DateTime _dayofMonth(DateTime month, bool back) {
    if (back) {
      final date = month.month == 1
          ? DateTime.utc(month.year - 1, 12, 1)
          : DateTime.utc(month.year, month.month - 1, 1);
      return date;
    } else {
      final date = month.month < 12
          ? DateTime.utc(month.year, month.month + 1, 1)
          : DateTime.utc(month.year + 1, 1, 1);
      return date;
    }
  }

  // print(DateFormat('EEE',"en_US").format(DateTime.now())); //Fri
  // print(DateFormat('EEEE',"en_US").format(DateTime.now())); //Friday
  // print(DateFormat('MM',"en_US").format(DateTime.now())); //11
  // print(DateFormat('MMM',"en_US").format(DateTime.now())); //Nov
  // print(DateFormat('MMMM',"en_US").format(DateTime.now())); //November

  // //指定locale为zh_CN
  // print(DateFormat('EEE',"zh_CN").format(DateTime.now())); //周五
  // print(DateFormat('EEEE',"zh_CN").format(DateTime.now())); //星期五
  // print(DateFormat('MM',"zh_CN").format(DateTime.now())); //11
  // print(DateFormat('MMM',"zh_CN").format(DateTime.now())); //11月
  // print(DateFormat('MMMM',"zh_CN").format(DateTime.now()));//十一月

  Widget list() {
    var language = Intl.getCurrentLocale();
    var firstDay = _firstDayOfMonth();
    var lastDay = _lastDayOfMonth();
    int differenceDay = lastDay.difference(firstDay).inDays;
    monthDayList = [];

    for (var i = 0; i < differenceDay; i++) {
      var day =
          DateTime.utc(2023, i > 5 ? 8 : 7, i > 5 ? (i - 4) : firstDay.day + i);
      var dayString = DateFormat('EEE', language).format(day);
      var monthString = DateFormat('MMM', language).format(day);
      monthDayList.add(
          CalendarItemData(monthString, day.day.toString(), dayString, day));
    }
    // for (int i = firstDay.day; i <= lastDay.day; i++) {
    //   var day = DateTime.utc(firstDay.year, firstDay.month, i);
    //   var dayString = DateFormat('EEE', language).format(day);
    //   var monthString = DateFormat('MMM', language).format(day);
    //   monthDayList.add(
    //       CalendarItemData(monthString, day.day.toString(), dayString, day));
    // }
    return Container(
      height: 76,
      child: ListView.separated(
        padding: EdgeInsets.symmetric(horizontal: 8),
        itemBuilder: (BuildContext context, int index) {
          return _cell(monthDayList[index]);
        },
        separatorBuilder: (BuildContext context, int index) {
          return SizedBox(width: 4);
        },
        itemCount: monthDayList.length,
        scrollDirection: Axis.horizontal,
        controller: controller,
      ),
    );
  }

  var now =
      DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day);
  Widget _cell(CalendarItemData model) {
    return GestureDetector(
      onTap: ClickUtils.debounce(() {
        _showTime = model.date;
        widget.action.back(model.date);
      }),
      child: Container(
        width: 60,
        decoration: BoxDecoration(
          shape: BoxShape.rectangle,
          borderRadius: BorderRadius.all(Radius.circular(8)),
          color: _getDataColor(model.date),
        ),
        padding: EdgeInsets.only(top: 8),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text(
              model.month,
              style: TextStyle(fontSize: 12, fontWeight: FontWeight.w400),
            ),
            SizedBox(
              height: 2,
            ),
            Text(
              model.day,
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
            ),
            SizedBox(
              height: 2,
            ),
            Text(
              (isSameDay(model.date, now))
                  ? S.of(context).week_today
                  : model.dayName,
              style: TextStyle(fontSize: 11, fontWeight: FontWeight.w400),
              textAlign: TextAlign.center,
            ),
          ],
        ),
      ),
    );
  }

  Color _getDataColor(DateTime day) {
    //同一天
    if (isSameDay(day, date)) {
      return ThemeColor.primaryColor;
    }
    // 不可用
    else if (_isDayDisabled(day, now)) {
      return Color(0xffEEEEEE);
    }
    // 今天以后
    else {
      return ThemeColor.bkColorFFFFFF;
    }
  }
}

bool isSameDay(DateTime? a, DateTime? b) {
  if (a == null || b == null) {
    return false;
  }

  return a.year == b.year && a.month == b.month && a.day == b.day;
}

bool _isDayDisabled(DateTime day, DateTime day2) {
  var res = day.compareTo(day2);
  return res < 0 ? true : false;
}

class CalendarItemData {
  final String month;
  final String day;
  final String dayName;
  final DateTime date;
  CalendarItemData(this.month, this.day, this.dayName, this.date);
}

Future<void> showFilterDialog(context, EventCalendarAction action) async {
  return showDialog<void>(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
      return Padding(
        padding: const EdgeInsets.all(15),
        child: Material(
          type: MaterialType.transparency,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                decoration: ShapeDecoration(
                  color: ThemeColor.bkColorFFFFFF,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.all(
                      Radius.circular(16.0),
                    ),
                  ),
                ),
                padding: const EdgeInsets.fromLTRB(0, 20, 0, 20),
                child: Column(
                  children: [
                    Container(
                      // height: 450,
                      color: Colors.white,
                      child: Column(
                        children: [
                          Container(
                            // color: Colors.red,
                            height: 410,
                            padding: EdgeInsets.symmetric(horizontal: 15),
                            child: CalendarTableBasics(
                                action: EventCalendarAction((v) {
                              Navigator.of(context).pop();
                              action.back(v);
                            }, action.selectDay, action.matchList)),
                          ),
                          Container(
                            padding: EdgeInsets.symmetric(horizontal: 15),
                            child: ElevatedButton(
                                child: Text(
                                  S.of(context).cancel,
                                  style: TextStyle(fontWeight: FontWeight.bold),
                                ),
                                onPressed: ClickUtils.debounce(
                                  () async {
                                    Navigator.of(context).pop();
                                  },
                                )),
                            height: 50,
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              )
            ],
          ),
        ),
      );
    },
  );
}

typedef void FuncBackToday(T);

class EventCalendarAction {
  final FuncBackToday back;
  DateTime selectDay;
  final List<DateTime> matchList;
  EventCalendarAction(this.back, this.selectDay, this.matchList);
}

class CalendarTableBasics extends StatefulWidget {
  CalendarTableBasics({Key? key, required this.action}) : super(key: key);
  final EventCalendarAction action;
  @override
  _TableBasicsState createState() => _TableBasicsState();
}

class _TableBasicsState extends State<CalendarTableBasics> {
  CalendarFormat _calendarFormat = CalendarFormat.month;
  DateTime _focusedDay = DateTime.now();
  DateTime? _selectedDay;
  final kFirstDay = DateTime(
      DateTime.now().year - 2, DateTime.now().month, DateTime.now().day);
  final kLastDay = DateTime(
      DateTime.now().year + 2, DateTime.now().month, DateTime.now().day);
  @override
  void initState() {
    _focusedDay = widget.action.selectDay;
    super.initState();

    //  =  DateTime.now();
  }

  bool checkHaveMatch(DateTime time) {
    var tmp = widget.action.matchList
        .map((e) {
          return isSameDay(time, e);
        })
        .toList()
        .where((element) => element)
        .toList();
    return tmp.length > 0;
  }

  @override
  Widget build(BuildContext context) {
    _selectedDay = widget.action.selectDay;
    return Scaffold(
        body: Container(
      // height: 450,
      // color: Colors.red,
      child: TableCalendar(
        daysOfWeekHeight: 20,
        calendarBuilders: CalendarBuilders(selectedBuilder: (ctx, day1, day2) {
          // 选中
          return Center(
            child: Container(
              width: 40,
              height: 40,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.all(Radius.circular(20)),
                color: ThemeColor.primaryColor,
              ),
              child: Center(
                child: Text('${day1.day}'),
              ),
            ),
          );
        }, todayBuilder: (ctx, day1, day2) {
          //当天
          return Stack(
            children: [
              Center(
                child: Container(
                  width: 40,
                  height: 40,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(Radius.circular(20)),
                    color: ThemeColor.colorBlack20,
                  ),
                  child: Center(
                    child: Text('${day1.day}'),
                  ),
                ),
              ),
              if (checkHaveMatch(day1))
                Positioned(
                  child: Container(
                    height: 8,
                    width: 8,
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.all(Radius.circular(4)),
                      color: ThemeColor.primaryColor,
                    ),
                  ),
                  right: 7,
                  top: 7,
                ),
            ],
          );
        }, defaultBuilder: (ctx, day1, day2) {
          //这是非当天，非选中的普通状态
          return Stack(
            children: [
              Center(
                child: Container(
                  width: 40,
                  height: 40,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(Radius.circular(20)),
                    color: Colors.white,
                  ),
                  child: Center(
                    child: Text('${day1.day}'),
                  ),
                ),
              ),
              if (checkHaveMatch(day1))
                Positioned(
                  child: Container(
                    height: 8,
                    width: 8,
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.all(Radius.circular(4)),
                      color: ThemeColor.primaryColor,
                    ),
                  ),
                  right: 7,
                  top: 7,
                ),
            ],
          );
        }),
        headerStyle: HeaderStyle(
          formatButtonVisible: false,
          titleCentered: true,
        ),
        availableGestures: AvailableGestures.horizontalSwipe,
        firstDay: kFirstDay,
        lastDay: kLastDay,
        focusedDay: _focusedDay,
        calendarFormat: _calendarFormat,
        selectedDayPredicate: (day) {
          return isSameDay(_selectedDay, day);
        },
        onDaySelected: (selectedDay, focusedDay) {
          if (!isSameDay(_selectedDay, selectedDay)) {
            setState(() {
              _selectedDay = selectedDay;
              _focusedDay = focusedDay;
            });
            widget.action.back(selectedDay);
          }
        },
        onFormatChanged: (format) {
          if (_calendarFormat != format) {
            // Call `setState()` when updating calendar format
            setState(() {
              _calendarFormat = format;
            });
          }
        },
        onPageChanged: (focusedDay) {
          // No need to call `setState()` here
          _focusedDay = focusedDay;
        },
      ),
    ));
  }
}
